<template>
	<div class="shortcut-manager">
		<div v-if="loading" class="home-loading">
			<el-icon class="loading-icon"><Loading /></el-icon>
			<div class="loading-text">加载中...</div>
		</div>

		<div v-else-if="shortcuts.length === 0" class="home-empty">
			<el-icon class="empty-icon"><Collection /></el-icon>
			<div class="empty-text">暂无常用功能</div>
			<div class="empty-desc">点击右上角添加您常用的功能</div>
		</div>

		<!-- 分页模式：当菜单数量超过每页显示数量时启用 -->
		<div v-else-if="needPagination" class="shortcuts-carousel">
			<!-- 左侧滑动按钮 -->
			<button v-if="showNavButtons && canScrollLeft" class="carousel-nav prev" @click="scrollToPrev" title="上一页">
				<el-icon><ArrowLeft /></el-icon>
			</button>

			<!-- 滑动容器 -->
			<div class="shortcuts-container" ref="containerRef">
				<div class="shortcuts-scroll" ref="scrollRef">
					<div class="shortcuts-grid">
						<div v-for="(shortcut, index) in currentPageData" :key="shortcut.ID" class="shortcut-card" @click="handleShortcutClick(shortcut)">
							<div class="card-header">
								<div class="card-icon">
									<el-icon v-if="shortcut.IconType === 'element'">
										<component :is="getElementIconComponent(getElementIcon(shortcut.MenuIcon))" />
									</el-icon>
									<i v-else :class="shortcut.MenuIcon"></i>
								</div>
								<div class="card-actions">
									<button v-auth="'/api/SysUserFavorite/Edit'" class="card-action-btn edit-btn" @click.stop="editShortcut(shortcut)" title="编辑">
										<el-icon><Edit /></el-icon>
									</button>
									<button
										v-auth="'/api/SysUserFavorite/Delete'"
										class="card-action-btn delete-btn"
										@click.stop="deleteShortcut(shortcut.ID)"
										title="删除"
									>
										<el-icon><Delete /></el-icon>
									</button>
								</div>
							</div>
							<div class="card-content">
								<div class="card-title">{{ shortcut.MenuName }}</div>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 右侧滑动按钮 -->
			<button v-if="showNavButtons && canScrollRight" class="carousel-nav next" @click="scrollToNext" title="下一页">
				<el-icon><ArrowRight /></el-icon>
			</button>
		</div>

		<!-- 分页指示器 -->
		<div v-if="needPagination" class="pagination-indicator">
			<span class="page-info">{{ currentPage + 1 }} / {{ totalPages }}</span>
		</div>

		<!-- 普通模式：当菜单数量不超过每页显示数量时 -->
		<div v-else class="shortcuts-grid">
			<div v-for="(shortcut, index) in shortcuts" :key="shortcut.ID" class="shortcut-card" @click="handleShortcutClick(shortcut)">
				<div class="card-header">
					<div class="card-icon">
						<el-icon v-if="shortcut.IconType === 'element'">
							<component :is="getElementIconComponent(getElementIcon(shortcut.MenuIcon))" />
						</el-icon>
						<i v-else :class="shortcut.MenuIcon"></i>
					</div>
					<div class="card-actions">
						<button class="card-action-btn edit-btn" @click.stop="editShortcut(shortcut)" title="编辑">
							<el-icon><Edit /></el-icon>
						</button>
						<button class="card-action-btn delete-btn" @click.stop="deleteShortcut(shortcut.ID)" title="删除">
							<el-icon><Delete /></el-icon>
						</button>
					</div>
				</div>
				<div class="card-content">
					<div class="card-title">{{ shortcut.MenuName }}</div>
				</div>
			</div>
		</div>

		<!-- 新增/编辑对话框 -->
		<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px" :before-close="handleDialogClose" destroy-on-close>
			<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
				<el-form-item label="功能菜单" prop="menuPath">
					<el-cascader
						v-model="formData.menuPath"
						:options="menuOptions"
						:props="cascaderProps"
						placeholder="请选择功能菜单"
						style="width: 100%"
						clearable
						@change="handleMenuChange"
					/>
				</el-form-item>
				<el-form-item label="功能名称" prop="MenuName">
					<el-input v-model="formData.MenuName" placeholder="请输入功能名称" />
				</el-form-item>
				<el-form-item label="图标" prop="MenuIcon">
					<IconSelector v-model="formData.MenuIcon" placeholder="请选择图标" @get="handleIconChange" @clear="handleIconClear" />
				</el-form-item>
				<el-form-item label="链接地址" prop="MenuUrl">
					<el-input v-model="formData.MenuUrl" placeholder="自动获取或手动输入链接地址" :disabled="!!formData.menuPath" />
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="handleDialogClose">取消</el-button>
					<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
import { ref, computed, defineAsyncComponent, onMounted, onUnmounted, nextTick, watch } from 'vue';
import type { Component } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import {
	Collection,
	Plus,
	Edit,
	Delete,
	User,
	Calendar,
	Money,
	Loading,
	ArrowLeft,
	ArrowRight,
	Bell,
	CircleCheck,
	Clock,
	Document,
	Promotion,
	Grid,
} from '@element-plus/icons-vue';
import { useRoutesList } from '/@/stores/routesList';
import { storeToRefs } from 'pinia';
import shortcutsApi, { type ShortcutData, type ShortcutVm, type ShortcutSearchResult } from '/@/api/shortcuts';
import { useShortcutsStore, type Shortcut } from '/@/stores/shortcuts';
import { useRouter } from 'vue-router';
import mittBus from '/@/utils/mitt';

// 引入图标选择器组件
const IconSelector = defineAsyncComponent(() => import('/@/components/iconSelector/index.vue'));

interface FormData {
	MenuName: string;
	menuPath: string;
	MenuIcon: string;
	MenuUrl: string;
	MenuId: string;
}

interface MenuItem {
	value: string;
	label: string;
	children?: MenuItem[];
	path?: string;
	id?: string;
	disabled?: boolean;
}

const emit = defineEmits(['menu-selector-visible']);

// 使用全局状态管理
const shortcutsStore = useShortcutsStore();
const { shortcuts, loading } = storeToRefs(shortcutsStore);
const router = useRouter();

// 滑动相关
const containerRef = ref<HTMLElement>();
const scrollRef = ref<HTMLElement>();
const canScrollLeft = ref(false);
const canScrollRight = ref(false);
const showNavButtons = ref(false);

// 分页相关
const currentPage = ref(0);
const cardsPerRow = ref(6);
const rowsPerPage = 3;

// 对话框相关
const dialogVisible = ref(false);
const isEditing = ref(false);
const editingId = ref<string>('');
const submitLoading = ref(false);
const formRef = ref();

// 表单数据
const formData = ref<FormData>({
	MenuName: '',
	menuPath: '',
	MenuIcon: '',
	MenuUrl: '',
	MenuId: '',
});

// 表单验证规则
const formRules = {
	MenuName: [{ required: true, message: '请输入功能名称', trigger: 'blur' }],
	MenuIcon: [{ required: true, message: '请选择图标', trigger: 'change' }],
	MenuUrl: [{ required: true, message: '请输入链接地址', trigger: 'blur' }],
};

// 菜单选项
const menuOptions = ref<MenuItem[]>([]);

// 级联选择器属性
const cascaderProps = {
	checkStrictly: true,
	emitPath: false,
	value: 'value',
	label: 'label',
	children: 'children',
	disabled: 'disabled',
};

// 对话框标题
const dialogTitle = computed(() => {
	return isEditing.value ? '编辑常用功能' : '添加常用功能';
});

// 获取路由信息
const routesListStore = useRoutesList();
const { routesList } = storeToRefs(routesListStore);

// 计算分页相关数据
const cardsPerPage = computed(() => cardsPerRow.value * rowsPerPage);

const pagedShortcuts = computed(() => {
	if (shortcuts.value.length <= cardsPerPage.value) {
		return [shortcuts.value];
	}

	const pages: Shortcut[][] = [];
	for (let i = 0; i < shortcuts.value.length; i += cardsPerPage.value) {
		pages.push(shortcuts.value.slice(i, i + cardsPerPage.value));
	}
	return pages;
});

const needPagination = computed(() => shortcuts.value.length > cardsPerPage.value);

const totalPages = computed(() => pagedShortcuts.value.length);

const currentPageData = computed(() => {
	if (pagedShortcuts.value.length === 0) return [];
	return pagedShortcuts.value[currentPage.value] || [];
});

// 更新每行卡片数量
const updateCardsPerRow = () => {
	if (!containerRef.value) return;

	const containerWidth = containerRef.value.clientWidth;
	let newCardsPerRow = 6;

	if (containerWidth <= 480) {
		newCardsPerRow = 4;
	} else if (containerWidth <= 768) {
		newCardsPerRow = 5;
	}

	if (newCardsPerRow !== cardsPerRow.value) {
		cardsPerRow.value = newCardsPerRow;
		currentPage.value = 0;
	}
};

// 更新分页状态
const updatePaginationState = () => {
	if (!needPagination.value) {
		showNavButtons.value = false;
		canScrollLeft.value = false;
		canScrollRight.value = false;
		return;
	}

	showNavButtons.value = true;
	canScrollLeft.value = currentPage.value > 0;
	canScrollRight.value = currentPage.value < totalPages.value - 1;

	if (currentPage.value >= totalPages.value) {
		currentPage.value = Math.max(0, totalPages.value - 1);
	}
};

// 刷新布局
let refreshTimer: NodeJS.Timeout | null = null;
const forceRefreshLayout = () => {
	if (refreshTimer) {
		clearTimeout(refreshTimer);
	}
	refreshTimer = setTimeout(() => {
		nextTick(() => {
			updateCardsPerRow();
			updatePaginationState();
		});
	}, 10);
};

const immediateRefreshLayout = () => {
	nextTick(() => {
		updateCardsPerRow();
		updatePaginationState();
	});
};

// 上一页
const scrollToPrev = () => {
	if (currentPage.value > 0) {
		currentPage.value--;
		updatePaginationState();
	}
};

// 下一页
const scrollToNext = () => {
	if (currentPage.value < totalPages.value - 1) {
		currentPage.value++;
		updatePaginationState();
	}
};

// 初始化菜单选项
const initMenuOptions = () => {
	const convertRouteToMenuItem = (route: any): MenuItem | null => {
		if (route.meta?.isHide) {
			return null;
		}
		const validChildren =
			route.children && route.children.length > 0
				? route.children.map((child: any) => convertRouteToMenuItem(child)).filter((child: MenuItem | null): child is MenuItem => child !== null)
				: [];

		const hasChildren = validChildren.length > 0;
		const isParentOnly = hasChildren;

		const menuId = route.name;
		const isAlreadyAdded = shortcuts.value.some((shortcut) => {
			if (isEditing.value && shortcut.ID === editingId.value) {
				return false;
			}
			return shortcut.MenuId === menuId || shortcut.MenuUrl === route.path;
		});

		const menuItem: MenuItem = {
			value: route.path,
			label: route.meta?.title || route.name || route.path,
			path: route.path,
			id: route.name,
			disabled: isParentOnly || isAlreadyAdded,
		};

		if (validChildren.length > 0) {
			menuItem.children = validChildren;
		}

		return menuItem;
	};

	if (routesList.value && routesList.value.length > 0) {
		menuOptions.value = routesList.value.map(convertRouteToMenuItem).filter((item): item is MenuItem => item !== null);
	}
};

// 处理菜单选择变化
const handleMenuChange = (value: string) => {
	if (value) {
		const findMenuItem = (items: MenuItem[], targetValue: string): MenuItem | null => {
			for (const item of items) {
				if (item.value === targetValue) {
					return item;
				}
				if (item.children) {
					const found = findMenuItem(item.children, targetValue);
					if (found) return found;
				}
			}
			return null;
		};

		const selectedMenuItem = findMenuItem(menuOptions.value, value);
		if (selectedMenuItem && !selectedMenuItem.disabled) {
			const menuId = selectedMenuItem.id || value;
			const isDuplicate = shortcuts.value.some((shortcut) => shortcut.MenuId === menuId || shortcut.MenuUrl === value);

			if (isDuplicate) {
				ElMessage.warning('该功能已添加到常用功能中，请勿重复添加');
				formData.value.menuPath = '';
				return;
			}

			formData.value.MenuUrl = value;
			formData.value.MenuId = menuId;
			if (!formData.value.MenuName) {
				formData.value.MenuName = selectedMenuItem.label;
			}
		}
	}
};

// 处理图标选择
const handleIconChange = (iconClass: string) => {
	formData.value.MenuIcon = iconClass;
};

// 处理图标清空
const handleIconClear = () => {
	formData.value.MenuIcon = '';
};

// 处理快捷方式点击
const handleShortcutClick = (shortcut: Shortcut) => {
	if (shortcut.MenuUrl) {
		router.push(shortcut.MenuUrl);
	}
};

// 编辑快捷方式
const editShortcut = (shortcut: Shortcut) => {
	isEditing.value = true;
	editingId.value = shortcut.ID;

	formData.value = {
		MenuName: shortcut.MenuName,
		menuPath: shortcut.MenuUrl,
		MenuIcon: shortcut.MenuIcon,
		MenuUrl: shortcut.MenuUrl,
		MenuId: shortcut.MenuId || '',
	};

	dialogVisible.value = true;
};

// 删除快捷方式
const deleteShortcut = async (id: string) => {
	try {
		await ElMessageBox.confirm('确定删除此常用功能吗？', '确认删除', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning',
		});

		await shortcutsStore.deleteShortcut(id);
		ElMessage.success('删除成功');
		immediateRefreshLayout();
	} catch (error: any) {
		if (error !== 'cancel') {
			ElMessage.error('删除失败');
		}
	}
};

// 重置表单
const resetForm = () => {
	formData.value = {
		MenuName: '',
		menuPath: '',
		MenuIcon: '',
		MenuUrl: '',
		MenuId: '',
	};
	formRef.value?.clearValidate();
};

// 处理对话框关闭
const handleDialogClose = () => {
	dialogVisible.value = false;
	resetForm();
};

// 提交表单
const handleSubmit = async () => {
	try {
		await formRef.value?.validate();

		if (!isEditing.value) {
			const isDuplicate = shortcuts.value.some(
				(shortcut) => shortcut.MenuId === formData.value.MenuId || shortcut.MenuUrl === formData.value.MenuUrl
			);

			if (isDuplicate) {
				ElMessage.warning('该功能已添加到常用功能中，请勿重复添加');
				return;
			}
		}

		submitLoading.value = true;

		const iconType = formData.value.MenuIcon.startsWith('ele-') ? 'element' : 'custom';

		const apiData: ShortcutVm = {
			Entity: {
				MenuId: formData.value.MenuId || formData.value.MenuUrl,
				MenuName: formData.value.MenuName,
				MenuIcon: formData.value.MenuIcon,
				MenuUrl: formData.value.MenuUrl,
				SortOrder: shortcuts.value.length + 1,
			},
		};

		if (isEditing.value) {
			apiData.Entity.ID = editingId.value;
			await shortcutsStore.editShortcut(apiData);
			ElMessage.success('编辑成功');
			immediateRefreshLayout();
		} else {
			await shortcutsStore.addShortcut(apiData);
			ElMessage.success('添加成功');
			immediateRefreshLayout();
		}

		handleDialogClose();
	} catch (error) {
		ElMessage.error(isEditing.value ? '编辑失败' : '添加失败');
	} finally {
		submitLoading.value = false;
	}
};

// 加载常用功能列表
const loadShortcuts = async () => {
	try {
		await shortcutsStore.loadShortcuts();
		nextTick(() => {
			updateCardsPerRow();
			updatePaginationState();
			initMenuOptions();
		});
		immediateRefreshLayout();
	} catch (error) {
		// 静默处理错误
	}
};

// 图标组件映射表
const iconComponentMap: Record<string, Component> = {
	User,
	Calendar,
	Money,
	Bell,
	CircleCheck,
	Clock,
	Document,
	Promotion,
};

// 获取Element Plus图标组件
const getElementIconComponent = (iconName: string): Component => {
	return iconComponentMap[iconName] || User;
};

// 获取Element Plus图标名称
const getElementIcon = (iconName: string): string => {
	const iconMap: Record<string, string> = {
		'ele-User': 'User',
		'ele-Calendar': 'Calendar',
		'ele-Money': 'Money',
		'ele-Bell': 'Bell',
		'ele-CircleCheck': 'CircleCheck',
		'ele-Clock': 'Clock',
		'ele-Document': 'Document',
		'ele-Promotion': 'Promotion',
	};
	return iconMap[iconName] || 'User';
};

// 监听shortcuts变化，重新初始化菜单选项
watch(
	[shortcuts, isEditing, editingId],
	() => {
		initMenuOptions();
	},
	{ deep: true }
);

// 监听shortcuts变化，更新分页状态
watch(
	shortcuts,
	() => {
		forceRefreshLayout();
	},
	{ deep: true, immediate: false }
);

// 监听shortcuts数量变化，确保布局及时更新
watch(
	() => shortcuts.value.length,
	() => {
		forceRefreshLayout();
	},
	{ immediate: false }
);

// 监听当前页变化，更新分页状态
watch(currentPage, () => {
	updatePaginationState();
});

// 组件挂载时初始化
onMounted(() => {
	loadShortcuts();

	nextTick(() => {
		updateCardsPerRow();
		updatePaginationState();
	});

	immediateRefreshLayout();

	window.addEventListener('resize', () => {
		immediateRefreshLayout();
	});

	mittBus.on('refreshShortcuts', () => {
		// 使用防抖刷新，避免频繁调用
		shortcutsStore.refreshShortcuts();
	});
});

// 组件卸载时清理事件监听
onUnmounted(() => {
	window.removeEventListener('resize', immediateRefreshLayout);
	mittBus.off('refreshShortcuts');

	if (refreshTimer) {
		clearTimeout(refreshTimer);
		refreshTimer = null;
	}
});
</script>

<style scoped>
.shortcut-manager {
	height: 100%;
	display: flex;
	flex-direction: column;
}

/* 滑动容器 */
.shortcuts-carousel {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--home-spacing-sm);
}

.shortcuts-container {
	flex: 1;
	overflow: hidden;
	border-radius: var(--home-radius-md);
}

.shortcuts-scroll {
	overflow: hidden;
	transition: var(--home-transition-base);
}

/* 网格布局 */
.shortcuts-grid {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: var(--home-spacing-md);
	padding: var(--home-spacing-sm) 0;
	max-width: 100%;
}

/* 卡片样式 */
.shortcut-card {
	width: 100%;
	aspect-ratio: 1;
	max-width: 120px;
	min-width: 80px;
	background: var(--home-bg-primary);
	border: 1px solid var(--home-border-lighter);
	border-radius: var(--home-radius-lg);
	cursor: pointer;
	transition: var(--home-transition-base), var(--home-transition-transform);
	position: relative;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	justify-self: center;

	&:hover {
		border-color: var(--home-primary-lighter);
		background: var(--home-bg-light);
		transform: translateY(-2px);
		box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);

		.card-actions {
			opacity: 1;
		}
	}

	&:active {
		transform: translateY(-1px);
	}
}

.card-header {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	position: relative;
	padding: var(--home-spacing-sm);
}

.card-icon {
	width: 48px;
	height: 48px;
	border-radius: var(--home-radius-md);
	background: var(--home-primary-lightest);
	color: var(--home-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: var(--home-spacing-xs);

	.el-icon {
		font-size: 24px;
	}

	i {
		font-size: 24px;
	}
}

.card-content {
	padding: 0 var(--home-spacing-xs) var(--home-spacing-sm);
	text-align: center;
}

.card-title {
	font-size: 12px;
	font-weight: 500;
	color: var(--home-text-primary);
	line-height: 1.2;
	text-overflow: ellipsis;
	overflow: hidden;
	white-space: nowrap;
}

/* 卡片操作按钮 */
.card-actions {
	position: absolute;
	top: 4px;
	right: 4px;
	display: flex;
	gap: 2px;
	opacity: 0;
	transition: var(--home-transition-fade);
}

.card-action-btn {
	width: 20px;
	height: 20px;
	border: none;
	border-radius: var(--home-radius-xs);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: var(--home-transition-base);

	.el-icon {
		font-size: 10px;
	}

	&.edit-btn {
		background: var(--home-primary-lightest);
		color: var(--home-primary);

		&:hover {
			background: var(--home-primary-lighter);
		}
	}

	&.delete-btn {
		background: var(--home-danger-lightest);
		color: var(--home-danger);

		&:hover {
			background: var(--home-danger-lighter);
		}
	}
}

/* 滑动导航按钮 */
.carousel-nav {
	width: 32px;
	height: 32px;
	border: 1px solid var(--home-border-light);
	border-radius: var(--home-radius-round);
	background: var(--home-bg-primary);
	color: var(--home-text-secondary);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: var(--home-transition-base);
	flex-shrink: 0;

	&:hover {
		border-color: var(--home-primary);
		color: var(--home-primary);
		background: var(--home-primary-lightest);
	}

	&:active {
		transform: scale(0.95);
	}

	.el-icon {
		font-size: 14px;
	}
}

/* 分页指示器 */
.pagination-indicator {
	display: flex;
	justify-content: center;
	align-items: center;
	margin-top: var(--home-spacing-sm);
	gap: var(--home-spacing-xs);

	.page-info {
		font-size: 12px;
		color: var(--home-text-secondary);
		background: var(--home-bg-light);
		padding: 4px 8px;
		border-radius: var(--home-radius-xs);
		border: 1px solid var(--home-border-lighter);
		min-width: 40px;
		text-align: center;
	}
}

/* 加载状态样式 */
.home-loading {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: var(--home-spacing-xl);
	color: var(--home-text-secondary);

	.loading-icon {
		font-size: 32px;
		margin-bottom: var(--home-spacing-md);
		animation: rotate 1s linear infinite;
	}

	.loading-text {
		font-size: 14px;
	}
}

.home-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: var(--home-spacing-xl);
	color: var(--home-text-secondary);

	.empty-icon {
		font-size: 48px;
		margin-bottom: var(--home-spacing-md);
		color: var(--home-text-placeholder);
	}

	.empty-text {
		font-size: 16px;
		font-weight: 500;
		margin-bottom: var(--home-spacing-xs);
	}

	.empty-desc {
		font-size: 14px;
		color: var(--home-text-placeholder);
	}
}

@keyframes rotate {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

/* 对话框样式 */
.dialog-footer {
	display: flex;
	justify-content: flex-end;
	gap: 12px;
}

/* 响应式设计 */
@media (max-width: 1200px) {
	.shortcuts-grid {
		grid-template-columns: repeat(6, 1fr);
	}

	.shortcut-card {
		max-width: 100px;
		min-width: 70px;
	}

	.card-icon {
		width: 40px;
		height: 40px;

		.el-icon,
		i {
			font-size: 20px;
		}
	}

	.card-title {
		font-size: 11px;
	}
}

@media (max-width: 768px) {
	.shortcuts-grid {
		grid-template-columns: repeat(5, 1fr);
		gap: var(--home-spacing-sm);
	}

	.shortcut-card {
		max-width: 90px;
		min-width: 60px;

		.card-actions {
			opacity: 1;
		}
	}

	.card-icon {
		width: 36px;
		height: 36px;

		.el-icon,
		i {
			font-size: 18px;
		}
	}

	.card-title {
		font-size: 10px;
	}
}

@media (max-width: 480px) {
	.shortcuts-grid {
		grid-template-columns: repeat(4, 1fr);
		gap: var(--home-spacing-xs);
	}

	.shortcut-card {
		max-width: 80px;
		min-width: 50px;
	}

	.card-icon {
		width: 32px;
		height: 32px;

		.el-icon,
		i {
			font-size: 16px;
		}
	}

	.card-title {
		font-size: 9px;
	}

	.carousel-nav {
		width: 28px;
		height: 28px;

		.el-icon {
			font-size: 12px;
		}
	}
}
</style>
